package org.brisling.oabs.queryService.base;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletResponse;

import org.brisling.authorize.shiro.ShiroSecurityService;
import org.brisling.base.domain.DataTableListDomain;
import org.brisling.base.domain.ExportExcelDomain;
import org.brisling.base.domain.ListDomain;
import org.brisling.base.service.AbstractBaseQueryService;
import org.brisling.common.ConstSysParam;
import org.brisling.common.SysConfig;
import org.brisling.common.exception.DangerousOperatorException;
import org.brisling.common.util.ExportUtil;
import org.brisling.common.util.JsonUtil;
import org.brisling.common.util.LongUtil;
import org.brisling.sysman.domain.Users;
import org.brisling.sysman.queryService.QueryDictionaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 
 * <p>Title: QueryBaseOAService</p>
 * <p>Description: bootstrap oa通用查询服务类</p>
 * <p>Company: tongking</p>
 * @author jackson wang
 * @since 1.0
 * @version 1.0
 * @date 2016年9月16日 上午12:31:45
 */

public abstract class QueryBaseOAService<T> extends AbstractBaseQueryService<T>{
	
	
	
	@Autowired
	private	ShiroSecurityService shiroSecurityService;
	@Autowired
	private QueryDictionaryService dicService;
	
	private static final String DEPT_CODE = "apply_deptid";
	
	private static final String QUERY_BIZ_ALL_CODE = "query_oa_all";
	
	
	@PersistenceContext(unitName=ConstSysParam.SUBSYSTEM_SYSMAN)
	@Autowired
	protected void setEntityManager(EntityManager entityManager){
		this.entityManager = entityManager;		
	}
	
	/**
	 * 获取指定名称的视图层对象（html）
	 * @param code
	 * @return
	 */
	
	public ModelAndView getPage(String code){
		String _code = code==null?"main":code;
		return new ModelAndView(String.format("/%1$s/%2$s", this.moduleName,_code));
	}
	
		
	/**
	 * 获取datatable listdomain数据
	 */
	public DataTableListDomain<T> getTableDomain(@RequestBody(required=false) String body){		
		
		Integer draw = getDraw(body);
		ListDomain<T> listDomain = super.getListDomainByConditionAndOrder(body, typeMap, orderMap,true);
		
		return list2Table(listDomain,draw);
	}
	
	
	/**
	 * 获取特定查询条件的业务数据记录
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getBizListDomain(String body){		
		
		Integer draw = getDraw(body);
		ListDomain<T> listDomain = super.getListDomainByConditionAndOrder(body, typeMap, orderMap,true);
		return list2Table(listDomain,draw);
	}
	/**
	 * 获取用户可操作的业务资源集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getOperateTask(String body){
		
		Map<String,Object> conditionMap = this.getBodyParam(body);
		
		return getOperateTask(conditionMap);
	}
	
	/**
	 * 获取用户可操作的业务资源集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getOperateTask(Map<String,Object> conditionMap){
		String sql = dicService.getSqlByBizcode("flow_can_operate");
		String userid = shiroSecurityService.getCurrentUserIdentify();		
		Integer draw = getDraw(conditionMap);
		ListDomain<T> listDomain = super.getUserTaskCanOperateListDomain(userid,sql, conditionMap);
		return list2Table(listDomain,draw);
	}
	
	/**
	 * 获取用户已签收业务资源集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserSignedTask(String body){
		
		Map<String,Object> conditionMap = this.getBodyParam(body);
		return getUserSignedTask(conditionMap);
	}
	
	/**
	 * 获取用户已签收业务资源集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserSignedTask(Map<String,Object> conditionMap){
		String sql = dicService.getSqlByBizcode("flow_signed");
		String userid = shiroSecurityService.getCurrentUserIdentify();		
		Integer draw = getDraw(conditionMap);
		ListDomain<T> listDomain = super.getUserSignedListDomain(userid,sql, conditionMap,null);
		return list2Table(listDomain,draw);
	}
	
	
	
	/**
	 * 获取用户未签收业务资源集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserUnsignedTask(String body){
		
		Map<String,Object> conditionMap = this.getBodyParam(body);
		return getUserUnsignedTask(conditionMap);
	}
	
	/**
	 * 获取用户未签收业务资源集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserUnsignedTask(Map<String,Object> conditionMap){
		String sql = dicService.getSqlByBizcode("flow_can_signed");
		String userid = shiroSecurityService.getCurrentUserIdentify();		
		Integer draw = getDraw(conditionMap);
		ListDomain<T> listDomain = super.getUserUnsignedListDomain(userid,sql, conditionMap,null);
		return list2Table(listDomain,draw);
	}
	
	
	/**
	 * 获取用户已完成业务数据集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserFinishedTask( String body){
		
		Map<String,Object> conditionMap = this.getBodyParam(body);
		
		return getUserFinishedTask(conditionMap);
	}
	
	/**
	 * 获取用户已完成业务数据集合
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserFinishedTask(Map<String,Object> conditionMap){
		String sql = dicService.getSqlByBizcode("flow_finished");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		
		if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, QUERY_BIZ_ALL_CODE))
			conditionMap = this.addDeptConditionToMap(userid,conditionMap, DEPT_CODE);
			
		Integer draw = getDraw(conditionMap);
		ListDomain<T> listDomain= super.getUserFinishedListDomain(sql, conditionMap,null);
		return list2Table(listDomain,draw);
	}
	
	
	/**
	 * 获取当前业务所有数据集合
	 */
	public DataTableListDomain<T> getAllTask(String body){
		
		Map<String,Object> conditionMap = this.getBodyParam(body);
		
		return getAllTask(conditionMap);
	}
	
	/**
	 * 获取当前业务所有数据集合
	 */
	public DataTableListDomain<T> getAllTask(Map<String,Object> conditionMap){
		String sql = dicService.getSqlByBizcode("medical_flow_all_task");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		
		if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, QUERY_BIZ_ALL_CODE))
			conditionMap = this.addDeptConditionToMap(userid,conditionMap, DEPT_CODE);
			
		Integer draw = getDraw(conditionMap);
		ListDomain<T> listDomain= super.getAllListDomain(sql, conditionMap,null);
		return list2Table(listDomain,draw);
	}
	
	
	/**
	 * 获取当前用户所管理部门特定业务模块的流程记录
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserManagedTask(@RequestBody(required=false) String body){
		
		Map<String,Object> conditionMap = this.getBodyParam(body);
		
		return getUserManagedTask(conditionMap);
	}
	
	/**
	 * 获取当前用户所管理部门特定业务模块的流程记录
	 * @param body
	 * @return
	 */
	public DataTableListDomain<T> getUserManagedTask(Map<String,Object> conditionMap){
		String sql = dicService.getSqlByBizcode("flow_managed_manageuser");
		String userid = shiroSecurityService.getCurrentUserIdentify();
		
		if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, QUERY_BIZ_ALL_CODE)){
			Users usr = SysConfig.getUsr(userid);
			if(this.isManageJob(userid)){
				conditionMap = this.addDeptConditionToMap(userid,conditionMap, DEPT_CODE);
			}else{
				Map<String,String> paramMap = (Map<String, String>) conditionMap.get(ConstSysParam.CONDITION_MAP_KEY);
				if(paramMap==null){
					paramMap = new HashMap<String,String>();
				}
				paramMap.put("user_id_", usr.getIdentify());
				conditionMap.put(ConstSysParam.CONDITION_MAP_KEY, paramMap);
				sql = dicService.getSqlByBizcode("flow_managed_normaluser"); 
			}
		}
		Integer draw = getDraw(conditionMap);
		ListDomain<T> listDomain= super.getUserManagedListDomain(sql, conditionMap,null);
		return list2Table(listDomain,draw);
	}
	
	/**
	 * 导出excel文件
	 * @param body	业务数据查询条件
	 * @param sqlid	模块导出配置id
	 * @param title	导出文件标题
	 * @param response	
	 */
	public void exportExcel(String body,String sqlid,String title,HttpServletResponse response){
		Map<String,Object> conditionMap = this.getBodyParam(body);
		exportExcel(conditionMap,sqlid,title,response);
	}
	
	/**
	 * 导出excel文件
	 * @param body	业务数据查询条件
	 * @param sqlid	模块导出配置id
	 * @param title	导出文件标题
	 * @param response	
	 */
	public void exportExcel(Map<String,Object> conditionMap,String sqlid,String title,HttpServletResponse response){
		DataTableListDomain<T> domains= this.getTaskListDomain(conditionMap);
		String configStr = dicService.getSqlByBizcode(sqlid);
		
		ObjectMapper mapper = JsonUtil.getMapper();
		JavaType _javaType = mapper.getTypeFactory().constructCollectionType(List.class, ExportExcelDomain.class);

		List<ExportExcelDomain> list = null;
		try {
			list =  mapper.readValue(configStr, _javaType);
		}catch(Exception e){
			e.printStackTrace();
		}
		ExportUtil<T> eu = new ExportUtil<T>(title,list,domains.getData());
		try {
			eu.exportByDomain(response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 根据流程状态查询特定模块的流程数据集合
	 * @param body	查询参数定义
	 * @return
	 */
	public DataTableListDomain<T> getTaskListDomain(String body){		
		
		
		Map<String,Object> conditionMap = this.getBodyParam(body);
		
		
		return getTaskListDomain(conditionMap);
	}
	
	/**
	 * 根据流程状态查询特定模块的流程数据集合
	 * @param conditionMap	查询参数定义
	 * @return
	 */
	public DataTableListDomain<T> getTaskListDomain(Map<String,Object> conditionMap){
		
		
		DataTableListDomain<T> domains = new DataTableListDomain<T>();
		
		if((conditionMap!=null) && (conditionMap.containsKey("condition"))){
			Map<String,String> cMap = (Map<String, String>) conditionMap.get(ConstSysParam.CONDITION_MAP_KEY);
			String _state = null;
			if((cMap!=null) && (cMap.containsKey("flow_state"))){
				_state = cMap.get("flow_state");				
			}else{
				_state = ConstSysParam.FLOW_CANOPERATE;
			}			
			switch(_state){
			case ConstSysParam.FLOW_CANOPERATE:
				domains = getOperateTask(conditionMap);
				break;
//			case ConstSysParam.FLOW_SIGNED:
//				domains = getUserSignedTask(body);
//				break;
//			case ConstSysParam.FLOW_UNSIGED:
//				domains = getUserUnsignedTask(body);
//				break;
			case ConstSysParam.FLOW_MANAGED:
				domains = getUserManagedTask(conditionMap);
				break;
			case ConstSysParam.FLOW_all:
				domains = getAllTask(conditionMap);
				break;
			 
			default:
				domains = getOperateTask(conditionMap);
				break;
			}
		}
		return domains;
	}
	
	
	
	
	/**
	 * 根据id查找业务记录
	 * @param id	用户id
	 * @return 用户信息记录 
	 */
	
	public T getOne(@RequestParam(value="id",required=false) Long id){
		return super.getOne(id);
	}
	
	/**
	 * 根据用户唯一编码查找用户信息
	 * @param identify	用户唯一编码
	 * @return 用户信息记录
	 */
	
	public T getOneByIdentify(@RequestParam(value="identify",required=false) String identify){	
		return super.getOneByIdentify(identify);
	}
	
	/**
	 * 根据用户唯一编码查找用户信息
	 * @param identify	用户唯一编码
	 * @return 用户信息记录
	 */
	
	public T getOneByField(@RequestParam(value="field",required=false) String field,
			@RequestParam(value="fieldVal",required=false) String fieldVal){	
		return super.getOneByIdentify(field,fieldVal);
	}
	
	
	
	/**
	 * 返回流程记录流程实例的执行记录
	 * @param body	包含procInstId在内的参数信息
	 * @return
	 */
	
	@RequestMapping("/flowHistoricsListDomain.action")
	public ListDomain<Object> getHistoricByProcInstId(@RequestBody(required=false) String body){
		
		String sql = dicService.getSqlByBizcode("flow_historics");				
		return super.getHistoricByProcInstId(body, sql);
	}
	
	/**
	 * 查询窗口满意度异常数据
	 * @return
	 *
	 */	
	
	public List<T> getWindowUnSatisfy(){		
		
		String sql =dicService.getSqlByBizcode("duties_abnormal_OATempDrugPurchase");		
		
		try {
			return super.getClassedAllList(sql, this.clazz);
		} catch (DangerousOperatorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 	
		return null;
	}
	
	/*
	 * 转化domain类型
	 */
	private DataTableListDomain<T> list2Table(ListDomain<T> listDomain,Integer draw){
		
		DataTableListDomain<T> tableDomain = new DataTableListDomain<T>();
		if(listDomain!=null){		
			tableDomain.setRecordsTotal(listDomain.getTotal().intValue());
			tableDomain.setRecordsFiltered(tableDomain.getRecordsTotal());
			tableDomain.setData(listDomain.getRows());
			tableDomain.setDraw(draw);
		}
		return tableDomain;
	}

	/*
	 * 获取datatable url请求计数器
	 */
	private Integer getDraw(String body){
		Map<String,Object> conditionMap = this.getBodyParam(body);
		return getDraw(conditionMap);
	}
	
	private Integer getDraw(Map<String,Object> conditionMap){
		if(conditionMap!=null){
			if(conditionMap.containsKey("draw")){
				Object obj = conditionMap.get("draw");
				if(obj!=null){
					return LongUtil.getIntValue(obj.toString(),null);
				}
			}
		}
		return null;
	}
}
